package com.apestech.api.condition.conlib;

import com.apestech.api.tables.TableExec;
import com.apestech.framework.db.SqlResultSet;
import com.apestech.framework.db.SqlSession;
import com.apestech.framework.db.callback.QueryCallBackHandler;
import com.apestech.framework.dictionary.modul.Table;
import com.apestech.framework.json.JSON;
import com.apestech.framework.json.JSONArray;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.sql.callback.MasterSaveInter;
import com.apestech.framework.util.DBPub;
import com.apestech.framework.util.DateUtil;
import com.apestech.framework.util.callback.IdKeyCallback;
import com.apestech.framework.util.callback.SpiltStrCallback;
import com.apestech.framework.xml.condition.modul.Condition;
import com.apestech.framework.xml.condition.modul.Dimension;
import com.apestech.framework.xml.table.modul.Tables;

import java.util.ArrayList;
import java.util.Map;

public class ConSave extends ConPub {

    private Condition condition;
    private SqlSession session;

    public ConSave(Condition condition) throws Exception {
        super(condition);
        this.condition=condition;
        session=condition.getSession();
    }

    public Object saveTable() throws Exception {
        return saveTable(null);
    }

    public Object saveTable(MasterSaveInter saveInter) throws Exception {
        Object idValue=null;
        for(int i=0; i<super.getTableSize(); i++){
            Tables tab=super.getTables().get(i);
            tab.setSaveInter(saveInter);
            TableExec table=new TableExec(session, tab);
            idValue=table.saveMasterTable();
        }
        return idValue;
    }

    public String saveTable(String mid, JSONObject input, MasterSaveInter saveInter) throws Exception {
        return saveTable(mid, input, saveInter, null);
    }

    public String saveTable(String mid, JSONObject input, MasterSaveInter saveInter, IdKeyCallback idKeyCallback) throws Exception {
        String tabName=condition.getTableKey().getTabName(mid);
        Tables tab=condition.getTablesById(tabName);
        if(!session.tableExists(tabName)){
            ConCreate conCreate=new ConCreate(condition);
            conCreate.createTable(tab);
        }
        boolean insert=false;
        if(input.get(session.getSpecialField().getConditionId())==null){
            insert=true;
        }
        input.put("CONTROL_TYPE", 0);
        if(condition.getControlType()!=null){
            input.put("CONTROL_TYPE", condition.getControlType());
        }
        tab.setSaveInter(saveInter);
        String sid=(String) session.getForDDL().saveMasterTable(tab, input, idKeyCallback);
        if(insert){
            saveSum(input, sid, mid);
        }
        return sid;
    }

    public void stopExec(String mid, JSONObject input, String personId) throws Exception {
        String tabName=condition.getTableKey().getTabName(mid);
        String zxTab=tabName+"_EXEC";

        String sql=" UPDATE EXE_CONDITION_STOP SET LAST_UPDATED_STAMP=SYSDATE, STATE=#{STATE}, APPROVE_UID_ID=#{APPROVE_UID_ID},APPROVE_DATE=SYSDATE, UPDATE_DATE=SYSDATE " +
                " WHERE STOP_ID=#{STOP_ID} AND TO_CHAR(LAST_UPDATED_STAMP, 'YYYYMMDD.HH24MISS')||'.000'=#{LAST_UPDATED_STAMP_OLD} ";
        JSONObject param=new JSONObject();
        param.put("STOP_ID", input.get("STOP_ID"));
        param.put("autoCompletion","0");
        param.put("STATE", "exec");
        param.put("APPROVE_UID_ID", personId);
        param.put("LAST_UPDATED_STAMP_OLD", input.get("LAST_UPDATED_STAMP"));
        if(session.getForUpdate().update(sql, param)==0){
            throw new Exception("当前数据已经改变，请重新操作！");
        }

        JSONArray list=JSON.toJSONArray(input.get("productRequireItems"));
        int len=list.size();
        for(int i=0; i<len; i++){
            JSONObject m=new JSONObject();
            m.putAll(input);
            m.putAll(list.get(i));

            ArrayList<String> mlist=m.getKeylist();
            int jlen=mlist.size();
            for(int j=0; j<jlen; j++){
                String key=mlist.get(j);
                Object obj=m.get(key);
                if(obj instanceof Map){
                    JSONObject json1=JSON.toJSON(obj);
                    m.put(key, json1.getString("ID"));
                } else {
                    m.put(key, obj);
                }
            }
            session.getForUpdate().deleteTable(zxTab, m);
        }
        JSONObject m=new JSONObject();
        m.put("STOP_ID", input.get("STOP_ID"));
        //session.getForUpdate().update(" UPDATE "+zxTab+"_STOP SET LAST_UPDATED_STAMP=SYSDATE WHERE STOP_ID=#{STOP_ID} ", m);
    }

    public void importSave(String mid, JSONObject input, String personId) throws Exception {
        String tabName=condition.getTableKey().getTabName(mid);
        String impTab=tabName+"_EXEC_I";
        String mxTab=tabName+"_ITEM";
        String zxTab=tabName+"_EXEC";

        String sql=" UPDATE EXE_CONDITION_IMPORT SET LAST_UPDATED_STAMP=SYSDATE, STATE=#{STATE}, APPROVE_UID_ID=#{APPROVE_UID_ID} " +
                " WHERE IMP_ID=#{IMP_ID} AND TO_CHAR(LAST_UPDATED_STAMP, 'YYYYMMDD.HH24MISS')||'.000'=#{LAST_UPDATED_STAMP_OLD} "; //"AND IMP_STATE>0 ";
        JSONObject param=new JSONObject();
        param.put("IMP_ID", input.get("IMP_ID"));
        param.put("autoCompletion","0");
        param.put("STATE", "exec");
        param.put("CONTROL_TYPE", 0);
        param.put("APPROVE_UID_ID", personId);
        param.put("APPROVE_DATE","SYSDATE");
        if(condition.getControlType()!=null){
            input.put("CONTROL_TYPE", condition.getControlType());
        }
        param.put("PRIORITY", 0);
        param.put("UPDATE_VALUE", 0);
        param.put("LAST_UPDATED_STAMP_OLD", input.get("LAST_UPDATED_STAMP"));
        if(session.getForUpdate().update(sql, param)==0){
            throw new Exception("当前数据已经改变，请重新操作！");
        }

        Table ztab=session.getDictTable(tabName);
        Table zxtab=session.getDictTable(zxTab);
        String zcol=ztab.getColumn();
        String zxkey=zxtab.getPkKey().getPkColumn();

        final String[] zxWhere = {""};

        param.clear();
        execSplitStr(zxkey, ";", new SpiltStrCallback() {
            @Override
            public void exec(String id) throws Exception {
                if((","+zcol+",").indexOf(","+id+",")>=0){
                    param.put(id, "1");
                    zxWhere[0] = zxWhere[0] +" AND "+id+"=#{"+id+"}";
                }
            }
        });
        String key=param.getKeyStr();
        key="A."+key.replace(";",",A.");

        sql="SELECT "+key+",COUNT(1) TS FROM "+impTab+" A WHERE 1=1 AND IMP_STATE=0  @WHERE@ "+
                " GROUP BY "+key;
        JSONObject map=new JSONObject();
        map.put("IMP_ID", input.getString("IMP_ID"));
        session.getForResultSet().sql(sql, map, new QueryCallBackHandler(){
            @Override
            public void getData(SqlResultSet rs, JSONArray rslist) throws Exception {
                while(rs.next()){
                    JSONObject r=rs.toRowJson();
                    r.put("IMP_ID", input.get("IMP_ID"));
                    String sid=saveZtab(r, tabName);
                    saveSum(r, sid, mid);
                    saveMxtab(r, mxTab, impTab, sid, zxWhere[0]);
                }
            }
        });
    }

    private void saveSum(JSONObject input, String cid, String mid) throws Exception {
        JSONObject m=new JSONObject();
        m.putAll(input);
        m.put("ID", DBPub.getIdKeyStr(session, "EXE_CONDITION_SUM"));
        m.put("CONDITION_ID", condition.getId());
        m.put("DIMENSION_ID", mid);
        m.put("B_ID", cid);
        m.put("CREATE_DATE", "SYSDATE");
        m.put("LAST_UPDATED_STAMP", "SYSDATE");
        session.getForUpdate().insertTable("EXE_CONDITION_SUM", m);
    }

    private String saveZtab(JSONObject input, String tabName) throws Exception {
        String sid=DBPub.getIdKeyStr(session, tabName);
        JSONObject r=new JSONObject();
        r.putAll(input);
        r.remove("TS");
        r.put("IMP_ID", input.get("IMP_ID"));
        r.put("ID", sid);
        if(r.get("STATE")==null){
            r.put("STATE", "sent");
        }
        r.put("CREATE_DATE", "SYSDATE");
        r.put("UPDATE_DATE", "SYSDATE");
        if(r.get("CREATOR_ID")==null){
            r.put("CREATOR_ID","yyadmin");
        }
        if(r.get("UPDATER_ID")==null){
            r.put("UPDATER_ID","yyadmin");
        }
        r.put("LAST_UPDATED_STAMP", "SYSDATE");
        r.put("START_DATE", DateUtil.getStartDate(r.getString("START_DATE")));
        r.put("END_DATE", DateUtil.getEndDate(r.getString("END_DATE")));
        r.put("CONTROL_TYPE", 0);
        if(condition.getControlType()!=null){
            r.put("CONTROL_TYPE", condition.getControlType());
        }
        //完善主表其它字段信息
        session.getForUpdate().insertTable(tabName, r);
        return sid;
    }

    private void saveMxtab(JSONObject input, String tabName, String impTab, String cid, String zxWhere) throws Exception {
        JSONObject m=new JSONObject();
        m.putAll(input);
        m.put("START_DATE", DateUtil.dateTimeToStr(m.getDate("START_DATE")));
        m.put("END_DATE", DateUtil.dateTimeToStr(m.getDate("END_DATE")));
        m.remove("ID");
        m.remove("MEMO");
        String sql="SELECT A.* FROM "+impTab+" A WHERE 1=1 ";
        session.getForResultSet().sql(sql, m, new QueryCallBackHandler(){
            @Override
            public void getData(SqlResultSet rs, JSONArray rslist) throws Exception {
                //完善从表其它字段信息
                while(rs.next()){
                    JSONObject mr=rs.toRowJson();
                    mr.putAll(input);
                    mr.put("MEMO", "原单号："+mr.getString("ID"));
                    mr.put("LAST_UPDATED_STAMP", "SYSDATE");
                    mr.put("ID", cid);
                    try{
                        session.getForUpdate().insertTable(tabName, mr);
                    } catch (Exception e){
                        String msg=e.getMessage();
                        if(msg.indexOf("违反唯一约束条件")>=0){
                            throw new Exception("请先处理掉【导入错误】页，问题记录之后，再执行【生成策略单号】操作！");
                        } else throw e;
                    }
                }
            }
        });
        m.put("ID", cid);
        m.put("START_DATE_N", DateUtil.getStartDate(input.getString("START_DATE")));
        m.put("END_DATE_N", DateUtil.getEndDate(input.getString("END_DATE")));
        m.put("START_DATE", DateUtil.strToDate(m.getString("START_DATE")));
        m.put("END_DATE", DateUtil.strToDate(m.getString("END_DATE")));
        m.put("START_DATE_N", DateUtil.strToDate(m.getString("START_DATE_N")));
        m.put("END_DATE_N", DateUtil.strToDate(m.getString("END_DATE_N")));
        sql="UPDATE "+impTab+" SET MEMO='原单号'||ID, ID=#{ID}, START_DATE=#{START_DATE_N}, END_DATE=#{END_DATE_N} WHERE 1=1 "+zxWhere;
        session.getForUpdate().update(sql, m);
    }

    public void execSave() throws Exception {
        ArrayList<String> msglist=new ArrayList<String>();
        ArrayList<Dimension> dlist=condition.getDimension();
        int len=dlist.size();
        for(int i=0; i<len; i++){
            String mid=dlist.get(i).getId();
            try{
                String tabName=condition.getTableKey().getTabName(mid);
                session.getForUpdate().update("DELETE "+tabName+"_ITEM");
                session.getForUpdate().update("DELETE "+tabName);
                session.getForUpdate().update("DELETE EXE_CONDITION_SUM WHERE CONDITION_ID='"+condition.getId()+"' AND DIMENSION_ID='"+mid+"'");
                DBPub.resetSeq(session, tabName);
                session.getForUpdate().update("UPDATE "+tabName+"_EXEC SET ID=SUBSTR(MEMO, 4,LENGTH(MEMO)), MEMO=NULL WHERE MEMO IS NOT NULL");
                execSave(mid, null);
            } catch (Exception e){
                msglist.add("策略"+condition.getId()+"维度"+mid+"错误信息："+e.toString());
            }
        }
        System.out.println("__________________ERROR_______________");
        System.out.println(JSON.toJSONString(msglist));
    }

    public void execSave(String mid, JSONObject input) throws Exception {
        if(input==null) input=new JSONObject();
        String tabName=condition.getTableKey().getTabName(mid);
        String mxTab=tabName+"_ITEM";
        String zxTab=tabName+"_EXEC";
        Table ztab=session.getDictTable(tabName);
        Table zxtab=session.getDictTable(zxTab);
        String zcol=ztab.getColumn();
        String zxkey=zxtab.getPkKey().getPkColumn();
        final String[] zxWhere = {""};
        JSONObject param=new JSONObject();
        execSplitStr(zxkey, ";", new SpiltStrCallback() {
            @Override
            public void exec(String id) throws Exception {
                if((","+zcol+",").indexOf(","+id+",")>=0){
                    param.put(id, "1");
                    zxWhere[0] = zxWhere[0] +" AND "+id+"=#{"+id+"}";
                }
            }
        });
        String key=param.getKeyStr();
        key="A."+key.replace(",",",A.");

        String sql="SELECT "+key+",COUNT(1) TS FROM "+zxTab+" A WHERE 1=1 @WHERE@ "+
                " GROUP BY "+key;//+" ORDER BY ID ";
        session.getForResultSet().sql(sql, input, new QueryCallBackHandler(){
            @Override
            public void getData(SqlResultSet rs, JSONArray rslist) throws Exception {
                while(rs.next()){
                    JSONObject r=rs.toRowJson();
                    r.put("STATE","exec");
                    if(r.get("APPROVE_UID_ID")==null){
                        r.put("APPROVE_UID_ID","yyadmin");
                    }
                    r.put("APPROVE_DATE","SYSDATE");
                    //r.put("MEMO","EXEC数据导入");
                    String sid=saveZtab(r, tabName);
                    saveSum(r, sid, mid);
                    saveMxtab(r, mxTab, zxTab, sid, zxWhere[0]);
                }
            }
        });
    }

}
